﻿HmJS.$Import('core.element');

/*
---
version: 1.0-20
description: TOC is a MooTools Plugin which turn a list of HTML headings into a Table of Content.
license: MIT-style license.
download: http://mootools.net/forge/p/TOC
source: http://github.com/thinkphp/TOC

authors:
- Adrian Statescu (http://thinkphp.ro).

requires:
core/1.2.1: '*'

provides: [TOC]
...
*/

HmJS.register('util.dom.TOC', function ($ns) {

	return new Class({

		/* implements */
		Implements: [Options],

		Binds: ['showHideToc'],

		/* options */
		options: {
			showHideToc: true,
			contentHeaderID: 'contentheader',
			showContentHeaderText: 'show page contents',
			hideContentHeaderText: 'hide page contents'
		},

		/* public method - constructor of class initialize */

		initialize: function (elem, options) {
			/* set options */
			this.setOptions(options);
			this.$tocState = 'block';
			this.$toc = $(elem);
			if (!this.$toc) { return; }
			this.createToc();
			this.$contentheader = $(this.options.contentHeaderID);
			if (this.options.showHideToc) {
				this.$contentheader.addEvent('click', this.showHideToc);
			}
		},

		/* private method */
		createToc: function () {
			var out = '<ul>';
			if (this.options.showHideToc) {
				out = '<span id="' + this.options.contentHeaderID + '">' + this.options.hideContentHeaderText + '</span><ul>';
			}

			var nodes = this.getElementsByTagNamess('h1,h2,h3,h4');
			var weight, oldweight, nextweight;

			nodes.each(function (o, k) {
				var id = o.id;
				if (id == '') {
					id = 'head' + k;
					o.id = id;
				}

				weight = o.nodeName.substr(1, 1);

				if (k > 0 && weight > oldweight) {
					out += '<ul>';
				}

				out += '<li><a href="#' + o.id + '">' + o.innerHTML + '</a>';

				if (nodes[k + 1]) {
					nextweight = nodes[k + 1].nodeName.substr(1, 1);
					if (weight > nextweight) {
						out += '</li></ul></li>';
					}

					if (weight == nextweight) {
						out += '</li>';
					}
				}

				oldweight = weight;
			});

			out += '</li></ul>';

			this.$toc.set('html', this.$toc.get('html') + out);
		},

		/* private method */
		getElementsByTagNamess: function (list, obj) {
			if (!obj) { var obj = document; }

			var tagNames = list.split(',');
			var resultArray = new Array();
			for (var i = 0; i < tagNames.length; i++) {
				var tags = obj.getElementsByTagName(tagNames[i]);
				for (var j = 0; j < tags.length; j++) {
					resultArray.push(tags[j]);
				}
			}

			var testNode = resultArray[0];
			if (!testNode) { return []; }
			if (testNode.sourceIndex) {
				resultArray.sort(function (a, b) {
					return a.sourceIndex - b.sourceIndex;
				});
			} else if (testNode.compareDocumentPosition) {
				resultArray.sort(function (a, b) {
					return 3 - (a.compareDocumentPosition(b) & 6);
				});
			}

			return resultArray;
		},

		/* 
		Handler for click event - 

		function which is triggered 

		when make click on the button 
		*/
		showHideToc: function () {
			var toc = this.$toc;

			this.$tocState = (this.$tocState === 'none') ? 'block' : 'none';

			this.$contentheader.set('text', (this.$tocState == 'none') ? this.options.showContentHeaderText : this.options.hideContentHeaderText);

			if (this.$tocState === 'none') {
				toc.setStyle('borderTop', '0px solid #EEF0EB');
				toc.setStyle('borderBottom', '0px solid #EEF0EB');
				toc.setStyle('backgroundColor', '');
			} else {
				toc.setStyle('borderTop', '1px solid #ccc');
				toc.setStyle('borderBottom', '1px solid #ccc');
				toc.setStyle('backgroundColor', '#fff');
			}

			toc.lastChild.style.display = this.$tocState;
		}

	});

});